package com.example.psychologicalappointmentsystem.service.impl.order;

import cn.hutool.core.bean.BeanUtil;
import com.example.psychologicalappointmentsystem.Constants.PropertyBean;
import com.example.psychologicalappointmentsystem.Controller.transform.DOToVo;
import com.example.psychologicalappointmentsystem.Entity.OrderDO;
import com.example.psychologicalappointmentsystem.Enum.OrderStatus;
import com.example.psychologicalappointmentsystem.Enum.PaymentStatus;
import com.example.psychologicalappointmentsystem.JpaRepository.OrderRepository;
import com.example.psychologicalappointmentsystem.Object.ConsultationTimeVO;
import com.example.psychologicalappointmentsystem.Object.OrderVO;
import com.example.psychologicalappointmentsystem.Object.alipayVO;
import com.example.psychologicalappointmentsystem.config.auth.PsyThreadLocalUtil;
import com.example.psychologicalappointmentsystem.service.AliPayService;
import com.example.psychologicalappointmentsystem.service.OrderService;
import com.example.psychologicalappointmentsystem.tools.DateTools;
import com.example.psychologicalappointmentsystem.tools.TransactionIdGenerator;
import com.google.common.collect.Lists;
import lombok.extern.slf4j.Slf4j;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.data.domain.Page;
import org.springframework.data.domain.PageRequest;
import org.springframework.data.domain.Pageable;
import org.springframework.http.HttpStatus;
import org.springframework.http.ResponseEntity;
import org.springframework.stereotype.Service;
import org.springframework.transaction.annotation.Transactional;

import java.time.LocalDate;
import java.time.LocalDateTime;
import java.time.format.DateTimeFormatter;
import java.util.ArrayList;
import java.util.Date;
import java.util.List;
import java.util.Objects;
import java.util.stream.Collectors;

@Service
@Slf4j
public class OrderServerImpl implements OrderService {
    @Autowired
    OrderRepository orderRepository;

    @Autowired
    AliPayService aliPayService;

    @Autowired
    private DOToVo doToVo;

    @Transactional
    @Override
    public ResponseEntity<?> createOrder(OrderVO orderVO) {
        try {
            orderVO.checkAdd();
            OrderDO orderDO = new OrderDO();
            BeanUtil.copyProperties(orderVO,orderDO);


            //设置默认值
            orderDO.setStatus(OrderStatus.TODO);
            orderDO.setPaymentStatus(PaymentStatus.NON_PAYMENT);
            orderDO.setPaymentMethod("aliPay");

            //生成交易号
            String TransactionCode = TransactionIdGenerator.generate();
            orderDO.setTransactionId(TransactionCode);
            orderDO.setCanceledMsg("");

            orderRepository.save(orderDO);

            return ResponseEntity.ok("保存订单成功！订单id :" + orderDO.getId());

        } catch (Exception e) {
            log.error("保存订单失败！" + e.getMessage(), e);
            return ResponseEntity.status(HttpStatus.INTERNAL_SERVER_ERROR).body("保存订单失败！");
        }

    }

    @Override
    public ResponseEntity<?> orderListPage(OrderVO orderVO) {
        try {
            orderVO.initDefaultPageSize();

            Pageable pageable = PageRequest.of(orderVO.getCurrent(), orderVO.getPageSize());

            //咨询师id有就返回咨询师订单列表
            if (Objects.nonNull(orderVO.getConsultantId()) && orderVO.getConsultantId() > 0) {
                Page<OrderDO> orderListPage = orderRepository.findByConsultantId(orderVO.getConsultantId(), pageable);

                //咨询师维度需要返回用户nickname
                // page转换成vo返回
                List<OrderVO> orderVOS = orderListPage.stream()
                        .map(order -> doToVo.orderDo_to_orderVo(order))
                        .collect(Collectors.toList());

                // 创建一个新的 Page 对象，使用修改后的 content 和原始 page 的其他信息
                Page<OrderVO> userVOS1 = DOToVo.updatePageContent(orderListPage,orderVOS);

                return ResponseEntity.ok(userVOS1);

            } else if (Objects.nonNull(orderVO.getUserId()) && orderVO.getUserId() > 0) {
                //用户id有就返回用户订单列表
                Page<OrderDO> orderListPage = orderRepository.findByUserId(orderVO.getUserId(), pageable);
                return ResponseEntity.ok(orderListPage);

            } else {
                //去数据库分页查询数据
                Page<OrderDO> orderListPage = orderRepository.findAll(pageable);
                return ResponseEntity.ok(orderListPage);
            }

        } catch (Exception e) {
            log.error("获取订单列表异常！" + e.getMessage(), e);
            return ResponseEntity.status(HttpStatus.INTERNAL_SERVER_ERROR).body("获取订单列表异常！");
        }
    }

    @Override
    public ResponseEntity<?> orderInfo(OrderVO orderVO) {
        try {
            orderVO.checkOrderId();
            OrderDO orderDO = orderRepository.findById(orderVO.getId()).get();

            return ResponseEntity.ok(orderDO);

        } catch (Exception e) {
            log.error("获取订单详情异常！" + e.getMessage(), e);
            return ResponseEntity.status(HttpStatus.INTERNAL_SERVER_ERROR).body("获取订单详情异常！");
        }
    }


    @Override
    public ResponseEntity<?> selectTime(ConsultationTimeVO consultationTimeVO) {
        LocalDate date = consultationTimeVO.getDate();
        List<String> slots = new ArrayList<>();
        //添加时间范围
        LocalDateTime startDateTime = date.atTime(PropertyBean.START_TIME);
        LocalDateTime endDateTime = date.atTime(PropertyBean.END_TIME);


        // 获取当天0点的时间
        LocalDateTime startOfDay = date.atStartOfDay();
        // 获取次日0点的时间，等同于当天24点
        LocalDateTime endOfDay = date.plusDays(1).atStartOfDay();
        // 转换为Date类型
        Date startDate = DateTools.convertToLocalDateAsDate(startOfDay);
        Date endDate = DateTools.convertToLocalDateAsDate(endOfDay);
        //获取咨询师已被占用的时间
        List<OrderDO> orderDOList = orderRepository.findOrdersByTimeFrame(consultationTimeVO.getConsultantId(), startDate, endDate);
        List<LocalDateTime> break_off = Lists.newArrayList();
        for (OrderDO orderDO : orderDOList) {
            break_off.add(DateTools.convertToDateLocalDateTime(orderDO.getStartTime()));
        }

        //遍历一天的时间
        for (LocalDateTime slotStart = startDateTime; slotStart.isBefore(endDateTime); ) {
            LocalDateTime slotEnd = slotStart.plusMinutes(PropertyBean.SLOT_INTERVAL_MINUTES);
            if (slotEnd.isAfter(endDateTime)) {
                break; // 如果下一个时间段超出结束时间，则停止循环
            }
            //去除已经被占用的时间
            if (break_off.contains(slotStart)) {
                slotStart = slotEnd;
                continue;
            }
            slots.add(slotStart.format(DateTimeFormatter.ofPattern("HH:mm")) + " - "
                    + slotEnd.format(DateTimeFormatter.ofPattern("HH:mm")));
            slotStart = slotEnd;
        }

        log.info(slots.toString());
        return ResponseEntity.ok(slots);
    }

    @Override
    public ResponseEntity<?> payment(Long id) {

        try {
            OrderDO orderDO = orderRepository.findById(id).get();

            alipayVO alipayVO = new alipayVO();
            alipayVO.setTrade_no(orderDO.getTransactionId());
            alipayVO.setTotal_amount(orderDO.getFee().toString());
            alipayVO.setSubject("咨询服务费");
            alipayVO.setDescription("");

            //修改库支付状态
            orderDO.setPaymentStatus(PaymentStatus.PAID);
            orderRepository.save(orderDO);

            String paymentUrl = aliPayService.pay(alipayVO);

            return ResponseEntity.ok(paymentUrl);

        } catch (Exception e) {
            log.error("获取支付链接错误！" + e.getMessage(), e);
            return ResponseEntity.status(HttpStatus.INTERNAL_SERVER_ERROR).body("获取支付链接错误！");
        }
    }

    //支付结果通知回调
    //todo 待开发
    @Override
    public ResponseEntity<?> paymentResult(Long id) {
        try {
            OrderDO orderDO = orderRepository.findById(id).get();
            orderDO.setPaymentStatus(PaymentStatus.PAID);

            return ResponseEntity.ok("支付回调成功");

        }catch (Exception e){
            log.error("回调通知异常！" + e.getMessage(), e);
            return ResponseEntity.status(HttpStatus.INTERNAL_SERVER_ERROR).body("回调通知异常！");
        }
    }

    @Override
    public ResponseEntity<?> consultantAccept(ConsultationTimeVO consultationTimeVO) {
        OrderDO orderDO = orderRepository.getById(consultationTimeVO.getOrderId());
        //咨询师接受状态，0-取消预约，1-接受预约
        if ("0".equals(consultationTimeVO.getAcceptStatus())){
            orderDO.setStatus(OrderStatus.CANCELED);
            orderDO.setCanceledMsg(consultationTimeVO.getCancelMsg());
            orderRepository.save(orderDO);
            return ResponseEntity.ok("取消预约成功");
        }else {
            orderDO.setStatus(OrderStatus.RESERVED);
            orderRepository.save(orderDO);
            return ResponseEntity.ok("接受预约成功");
        }
    }

    @Override
    public ResponseEntity<?> orderAcceptInfo() {

        try {
            Long userId = PsyThreadLocalUtil.get().getUserId();
            // 根据用户id查询订单,查询用户最近的一笔订单
            OrderDO orderDO = orderRepository.findByUserIdLast(userId);

            if (Objects.nonNull(orderDO)){
                return ResponseEntity.ok(orderDO);
            }else {
                return ResponseEntity.ok("暂无订单！");
            }
        }catch (Exception e){
            log.error("查询订单异常！" + e.getMessage(), e);
            return ResponseEntity.status(HttpStatus.INTERNAL_SERVER_ERROR).body("查询订单异常！");
        }
    }
}
